package com.pajk.user.api.dubbo;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.pajk.user.exception.CreditServiceException;
import com.pajk.user.model.CreditHis;

import com.pajk.user.api.CreditService;
import com.pajk.user.api.UserService;

import com.pajk.user.model.User;
import com.pajk.user.model.enums.ChannelType;

public class CreditServiceIT {
	ClassPathXmlApplicationContext appContext = null;
	CreditService creditService = null;
	UserService userService = null;
	// CreditRuleService creditRuleService = null;
	User user = null;
	String actionID = null;

	public static final String CHECKIN_EVERYDAY = "checkin_everyday";
	public static final String CHECKIN_FIRSTLOGIN = "checkin_firstlogin";
	public static final String LOWLEVEL_EVAL = "lowlevel_eval";
	public static final String HIGHLEVEL_EVAL = "highlevel_eval";
	public static final String CHECKIN_7DAYS = "checkin_7days";
	public static final String CHECKIN_14DAYS = "checkin_14days";
	public static final String CHECKIN_21DAYS = "checkin_21days";
	public static final String FAMILY_ADDFIRSTMEM = "family_addfirstmem";
	public static final String FAMILY_ADDFIRSTMEMANDEVAL = "family_addfirstmemandeval";
	public static final String INTE_TWEET = "inte_tweet";
	public static final String IMPLSPORTS_WALK = "implsports_walk";
	public static final String READ_HEALTHINFO = "read_healthinfo";
	public static final String READ_DIETINFO = "read_dietinfo";
	public static final String MENTAL_MUSIC = "mental_music";
	public static final String MENTAL_JOKE = "mental_joke";

	@BeforeClass
	public void setup() {
		this.appContext = new ClassPathXmlApplicationContext(
				"classpath:META-INF/spring/user-service-consumer.xml");
		this.appContext.start();
		String openId = "testAddCredit" + new Random().nextInt();
		Long phoneNumber = new Random().nextLong();

		this.creditService = ((CreditService) this.appContext
				.getBean("creditService"));
		this.userService = ((UserService) this.appContext
				.getBean("userService"));
		// this.creditRuleService = ((CreditRuleService) this.appContext
		// .getBean("creditRuleService"));

		this.user = this.userService.getOrCreateUserByOpenId(openId,
				ChannelType.WEIXIN);// this.userService.getUserById(98900404l);
		if (this.userService.updateMobile(user.getId(), phoneNumber)) {
			this.user = this.userService.getUserById(user.getId());
		}
	}

	@AfterClass
	public void teardown() {
		this.appContext.close();
	}

	@Test
	public void addCreditTest() {
		String openId = "testAddCredit" + new Random().nextInt();
		System.out.println(openId);
		try {
			Date actionTime = new Date();

			Long userId = user.getId();
			System.out.println(userId);
			int credit = 0;

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_FIRSTLOGIN, "weixin",
					actionTime).intValue();
			Assert.assertEquals(500, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_FIRSTLOGIN, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_EVERYDAY, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_EVERYDAY, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			// 第二天连续签到获得签到积分--jingkun
			Calendar cal = Calendar.getInstance();
			cal.setTime(actionTime);
			cal.add(Calendar.DATE, 1);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_EVERYDAY, "weixin",
					cal.getTime()).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), CHECKIN_EVERYDAY, "weixin",
					cal.getTime()).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), LOWLEVEL_EVAL, "weixin",
					actionTime).intValue();
			Assert.assertEquals(150, credit);

			// 再次初级评测，查看返回积分是否为0 --jingkun
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), LOWLEVEL_EVAL, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), HIGHLEVEL_EVAL, "weixin",
					actionTime).intValue();
			Assert.assertEquals(500, credit);

			// 再次终极评测，查看返回积分是否为0--jingkun
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), HIGHLEVEL_EVAL, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), FAMILY_ADDFIRSTMEM, "weixin",
					actionTime).intValue();
			Assert.assertEquals(20, credit);
			// 再次添加家人，查看返回积分是否为0 --jingkun
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), FAMILY_ADDFIRSTMEM, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), FAMILY_ADDFIRSTMEMANDEVAL,
					"weixin", actionTime).intValue();
			Assert.assertEquals(50, credit);
			// 添加家人评测后再次评测，查看返回积分是否为0
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), FAMILY_ADDFIRSTMEMANDEVAL,
					"weixin", actionTime).intValue();
			Assert.assertEquals(0, credit);

			// 先注释掉-
			// credit = this.creditService.addCredit(userId, INTE_TWEET,
			// "weixin", actionTime).intValue();
			// Assert.assertEquals(20, credit);
			// credit = this.creditService.addCredit(userId, INTE_TWEET,
			// "weixin", actionTime).intValue();
			// Assert.assertEquals(0, credit);

			// 指定首次吐槽的日期（时间写死到2014年5月5日，星期一，自然周开始于星期日）
			Date d = new Date(2014 - 1900, 4, 5);
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), INTE_TWEET, "weixin", d)
					.intValue();
			Assert.assertEquals(20, credit);
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), INTE_TWEET, "weixin", d)
					.intValue();
			Assert.assertEquals(0, credit);
			// 一周内再次吐槽（直接判断本周内的周六吐槽返回值是否是0；默认周六是自然周最后一天）
			cal.setTime(d);
			cal.add(Calendar.DATE, 5);
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), INTE_TWEET, "weixin",
					cal.getTime()).intValue();
			Assert.assertEquals(0, credit);
			// 进入下周后继续吐糟（默认自然周开始于星期日）
			cal.setTime(d);
			cal.add(Calendar.DATE, 6);
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), INTE_TWEET, "weixin",
					cal.getTime()).intValue();
			Assert.assertEquals(20, credit);
			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), INTE_TWEET, "weixin",
					cal.getTime()).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), IMPLSPORTS_WALK, "weixin",
					actionTime).intValue();
			Assert.assertEquals(50, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), IMPLSPORTS_WALK, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_HEALTHINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_HEALTHINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_HEALTHINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_HEALTHINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_HEALTHINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_DIETINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_DIETINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_DIETINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_DIETINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), READ_DIETINFO, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_MUSIC, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_MUSIC, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_MUSIC, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_MUSIC, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_MUSIC, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_JOKE, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_JOKE, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_JOKE, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_JOKE, "weixin",
					actionTime).intValue();
			Assert.assertEquals(5, credit);

			credit = this.creditService.addCredit(userId,
					UUID.randomUUID().toString(), MENTAL_JOKE, "weixin",
					actionTime).intValue();
			Assert.assertEquals(0, credit);
		
			int searchCount =5;//查询等待10秒
			while (this.user.getWanliCredits().intValue() != 1400
					&& searchCount > 0) {
				Thread.sleep(2000);
				this.user = this.userService.getUserById(this.user.getId());				
				searchCount--;
			}
			
			System.out.println(userId + "最后健康积分：" + this.user.getCredits());
			System.out.println(userId + "最后万里通积分："
					+ this.user.getWanliCredits());

			Assert.assertEquals(1400, this.user.getCredits().intValue());
			Assert.assertEquals(1400, this.user.getWanliCredits().intValue());

		} catch (Exception e) {
			System.err.println(e.toString());
			Assert.fail(e.toString());
		}
	}

	@Test(description = "积分余额不足", expectedExceptions = { CreditServiceException.class })
	public void reduceCreditNoEnoughTest() {
		this.creditService.reduceCredit(user.getId(), this.actionID,
				CHECKIN_EVERYDAY, 2000, "weixin");
	}

	@Test(description = "万里通ID为NULL", expectedExceptions = { CreditServiceException.class })
	public void reduceCreditWLTNULLTest() {
		User user1 = this.userService.getOrCreateUserByOpenId("testAddCredit"
				+ new Random().nextInt(), ChannelType.WEIXIN);
		this.creditService.reduceCredit(user1.getId(), this.actionID,
				CHECKIN_EVERYDAY, 1, "weixin");
	}

	@Test(dependsOnMethods = { "addCreditTest" }, description = "正常消费")
	public void reduceCreditTest() {
		// 查询当前用户的原始积分
		int orignCredit = creditService.queryWltCredit(user.getWanliId())
				.intValue();
		System.out.println("当前用戶的积分为：" + orignCredit);
		this.actionID = "actionID" + new Random().nextInt();//UUID.randomUUID().toString().substring(20);

		// 消费
		this.creditService.reduceCredit(user.getId(), this.actionID,
				CHECKIN_EVERYDAY, 1, "weixin");
		int currentCredit = creditService.queryWltCredit(user.getWanliId())
				.intValue();
		// 验证成功消费
		Assert.assertEquals(currentCredit, orignCredit - 1);

		// 同一个actionID再次提交消费申请
		this.creditService.reduceCredit(user.getId(), this.actionID,
				CHECKIN_EVERYDAY, 1, "weixin");

		int currentCreditNew = creditService.queryWltCredit(user.getWanliId())
				.intValue();
		// 验证没有多次扣除积分
		Assert.assertEquals(currentCredit, currentCreditNew);
		// System.out.println("Done.");
	}

	@Test(dependsOnMethods = { "reduceCreditTest" }, description = "取消积分消费")
	public void cancelReduceCreditTest() {
		int orignCredit = creditService.queryWltCredit(user.getWanliId())
				.intValue();
		// 取消消费,并返回积分余额
		int credit = this.creditService.cancelReduceCredit(user.getId(), 5, 5,
				CHECKIN_EVERYDAY, this.actionID);

		// 重新查询积分
		int currentCredit = creditService.queryWltCredit(user.getWanliId())
				.intValue();
		// 验证接口返回积分是否和积分余额一致
		Assert.assertEquals(currentCredit, credit);
		// 验证是否成功返回积分
		Assert.assertEquals(currentCredit, orignCredit + 5);
	}

	@Test(dependsOnMethods = { "addCreditTest" }, description = "查询历史积分记录")
	public void getCreditHisByInfoTest() {

		// 查询日期为NUll的情况
		List<CreditHis> creditHisList = this.creditService.getCreditHisByInfo(
				user.getId(), CHECKIN_EVERYDAY, null);
		Assert.assertEquals(2, creditHisList.size());

		// 查询日期为当天的，记录情况
		creditHisList = this.creditService.getCreditHisByInfo(user.getId(),
				CHECKIN_EVERYDAY, new Date());
		Assert.assertEquals(1, creditHisList.size());
	}
}